package co.fitstart.admin.web.controller.report;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.support.Page;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.web.utils.WebUtils;

import co.fitstart.admin.cache.accessor.PersistentAccessor;
import co.fitstart.admin.entity.report.CoachFinishedSchedule;
import co.fitstart.admin.entity.report.CoachFinishedScheduleReport;
import co.fitstart.admin.entity.report.FinishedCourseReportStatistics;
import co.fitstart.admin.entity.report.FinishedCourseSchedule;
import co.fitstart.admin.entity.report.ReportPrepare;
import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.CourseScheduleService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.service.ReportService;
import co.fitstart.admin.service.SiteService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;

@Controller
@RequestMapping("/finished-course-reports")
@MenuSetting("menu-report")
public class FinishedCourseReportController {
    
    @Autowired
    private SiteService siteService;
    
    @Autowired
    private ReportService reportService;
    
    @Autowired
    private CourseScheduleService courseScheduleService;
    
    @Autowired
    private PersistentAccessor persistentAccessor;
    
    @Autowired
    private PrincipalService principalService;
    
    /**
     * 
     * @param login
     * @param siteId
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-finished-course-report")
    public ModelAndView list(@Secure Login login,
                             @RequestParam(name = "site", required = false) Long siteId,
                             @RequestParam(name = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date,
                             @RequestParam(name = "period", required = false, defaultValue = "day") String period) {
        
        ModelAndView modelAndView = new ModelAndView("report/finished-course-report-list");
        
        Site site = null;
        if(login.hasSite()) {
            site = login.getSite();
        } else if(siteId != null) {
            site = siteService.load(siteId);
        }
        
        List<Site> sites = new ArrayList<>();
        
        ReportPrepare reportPrepare = new ReportPrepare(site, date, period);
        modelAndView.addAllObjects(reportPrepare.describeReport());
        
        Map<String, Map<String, FinishedCourseReportStatistics>> reports = new HashMap<>();
        
        if(login.isAreaManager() || login.isAreaServer()) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            sites = siteService.listSite(principal);
            
            if(!sites.isEmpty()) {
                if(siteId == null) {
                    reports = reportService.listFinishedCourseReportStatistics(sites, reportPrepare.getCurrentDate(), period);
                } else if(site != null && sites.contains(site)) {
                    reports = reportService.listFinishedCourseReportStatistics(site, reportPrepare.getCurrentDate(), period);
                }
            }
        } else {
            reports = reportService.listFinishedCourseReportStatistics(site, reportPrepare.getCurrentDate(), period);
        }
               
        modelAndView.addObject("reports", reports);
        
//        List<Long> yearCourseIds = reportService.listYearCourseId();
        int amount = 0;
        
//        if(siteId != null) {
//            for(Long yearCourseId : yearCourseIds) {
//                amount = amount + persistentAccessor.scheduleAmount(yearCourseId, siteId, period, reportPrepare.getCurrentDate());
//            }
//        } else {
//            if(!login.isAreaManager() && !login.isAreaServer()) {
//                sites = persistentAccessor.getSites();
//            }
//            
//            for(Site currentSite : sites) {
//                if(!currentSite.isDisabled()) {
//                    for(Long yearCourseId : yearCourseIds) {
//                        amount = amount + persistentAccessor.scheduleAmount(yearCourseId, currentSite.getId(), period, reportPrepare.getCurrentDate());
//                    }
//                }
//            }
//        }
        List<Site> selectedSites = persistentAccessor.getSites(login.getId());
        Map<String, Long> statistics = reportService.getFinishedCourseTotal(selectedSites, reports, amount);
        modelAndView.addObject("statistics", statistics);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param date
     * @param site
     * @param request
     * @param page
     * @return
     */
    @SuppressWarnings({ "unchecked", "unused" })
	@RequestMapping("/common-grid")
    public ModelAndView commonGrid(@Secure Login login,
                             @RequestParam(value = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date, 
                             @RequestParam(value = "site", required = false) Long siteId,
                             @RequestParam(name = "period", required = false, defaultValue = "day") String period,
                             HttpServletRequest request,
                             Page page) {
       
        ModelAndView modelAndView = new ModelAndView("report/finished-course-report-common-grid");
        
        Site site = null;
        if(!login.hasSite() && siteId != null) {
            site = siteService.load(siteId);
        }else if (login.hasSite()){
            site = login.getSite();
        }
        
        List<CourseSchedule> finishedSchedules = new ArrayList<>();
        
        if(site == null && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            if(!sites.isEmpty()) {
                finishedSchedules = courseScheduleService.listFinishedSchedule(sites, date, period, page);
            }
        } else {
            finishedSchedules = courseScheduleService.listFinishedSchedule(site, date, period, page);
        }
        
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(finishedSchedules)) {
        	List<Long> ids = CollectionUtils.extractPropertyList(finishedSchedules, "id");
        }
        
        modelAndView.addObject("finishedSchedules", finishedSchedules);
        modelAndView.addObject("total", finishedSchedules.size());
        
        modelAndView.addObject("page", page);
        
        modelAndView.addObject("refer", "list");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param date
     * @param site
     * @param request
     * @param page
     * @return
     */
    @RequestMapping("/coach-grid")
    public ModelAndView coachGrid(@Secure Login login,
                             @RequestParam(value = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date, 
                             @RequestParam(value = "site", required = false) Long siteId,
                             @RequestParam(name = "period", required = false, defaultValue = "day") String period,
                             HttpServletRequest request,
                             Page page) {
       
        ModelAndView modelAndView = new ModelAndView("report/finished-course-report-coach-grid");
        
        Site site = null;
        if(!login.hasSite() && siteId != null) {
            site = siteService.load(siteId);
        }else if (login.hasSite()){
            site = login.getSite();
        }
        
        List<CoachFinishedSchedule> finishedSchedules = new ArrayList<>();
        
        if(site == null && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            if(!sites.isEmpty()) {
                finishedSchedules = courseScheduleService.listCoachFinishedSchedule(sites, date, period, page);
            }
        } else {
            finishedSchedules = courseScheduleService.listCoachFinishedSchedule(site, date, period, page);
        }
                
        
        modelAndView.addObject("finishedSchedules", finishedSchedules);
        modelAndView.addObject("total", finishedSchedules.size());
        
        modelAndView.addObject("page", page);
        
        modelAndView.addObject("refer", "list");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    /**
     * 
     * @param siteId
     * @return
     */
    @RequestMapping(value = "/export-view", method = RequestMethod.GET)
    public ModelAndView export() {
        
        ModelAndView modelAndView = new ModelAndView("report/finished-course-report-export");
        
        modelAndView.addObject("today", DateFormatUtils.format(new Date(), "yyyy-MM-dd"));
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param view
     * @param siteId
     * @param beginDate
     * @param endDate
     * @return
     */
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ModelAndView onExport(@Secure Login login,
                                 @RequestParam(value = "site", required = false) Long siteId,
                                 @RequestParam(value = "beginDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginDate,
                                 @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("finished-course-report.xls"));
        
        // get site
        List<Site> sites = new ArrayList<>();
        Site site = null;
        if(login.hasSite()) {
            site = login.getSite();
        } else if(siteId != null) {
            site = siteService.load(siteId);
        }
        
        Map<String, Object> total = new HashMap<>();
        
        Map<String, List<CoachFinishedScheduleReport>> coachStats = new HashMap<>();
        Map<Long, Long> siteStats = new HashMap<>();
        List<FinishedCourseSchedule> schedules = new ArrayList<>();
        
        if(login.isAreaManager() || login.isAreaServer()) {
        	
            Principal principal = principalService.load(Principal.class, login.getId());
            List<Site> avaiableSites = siteService.listSite(principal);
            
            if(!avaiableSites.isEmpty()) {
                if(site != null && avaiableSites.contains(site)) {
                    total = reportService.getFinishedScheduleTotal(site, beginDate, endDate);
                    coachStats = reportService.listCoachFinishedScheduleReport(site, beginDate, endDate);
                    siteStats = reportService.getSiteFinishedScheduleStat(site, beginDate, endDate);
                    schedules = reportService.listFinishedCourseSchedule(site, beginDate, endDate);
                    
                    modelAndView.addObject("selectedSite", site);
                    sites.add(site);
                    modelAndView.addObject("sites", sites);
                } else {
                    total = reportService.getFinishedScheduleTotal(avaiableSites, beginDate, endDate);
                    coachStats = reportService.listCoachFinishedScheduleReport(avaiableSites, beginDate, endDate);
                    siteStats = reportService.getSiteFinishedScheduleStat(avaiableSites, beginDate, endDate);
                    schedules = reportService.listFinishedCourseSchedule(avaiableSites, beginDate, endDate);
                    modelAndView.addObject("selectedSite", null);
                    modelAndView.addObject("sites", avaiableSites);
                }
            }
            
        } else {
        	
            total = reportService.getFinishedScheduleTotal(site, beginDate, endDate);
            coachStats = reportService.listCoachFinishedScheduleReport(site, beginDate, endDate);
            siteStats = reportService.getSiteFinishedScheduleStat(site, beginDate, endDate);
            
            if(site == null) {
                sites = siteService.loadAll();
                schedules = reportService.listFinishedCourseSchedule(sites, beginDate, endDate);
                modelAndView.addObject("sites", sites);
                modelAndView.addObject("selectedSite", null);
                
            } else {
                schedules = reportService.listFinishedCourseSchedule(site, beginDate, endDate);
                
                modelAndView.addObject("selectedSite", site);
                sites.add(site);
                modelAndView.addObject("sites", sites);
            }
            
        }
        
        modelAndView.addObject("total", total);
        modelAndView.addObject("coachStats", coachStats);
        modelAndView.addObject("siteStats", siteStats);
        modelAndView.addObject("schedules", schedules);

        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        modelAndView.addObject("fmt", fmt);
        
        DateFormat fmtDay = new SimpleDateFormat("yyyy-MM-dd");
        modelAndView.addObject("fmtDay", fmtDay);
        
        NumberFormat decFmt = new DecimalFormat("0.00");
        modelAndView.addObject("decFmt", decFmt);
        
        return modelAndView;
    }

}
